package trab;

import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.FileTime;
import java.util.ArrayList;

//Teste
public class ChecksDirectories {

	private ArrayList<Backup> listaArquivos = new ArrayList<Backup>();
	private String caminhoOrigem = null;
	private String destino = null;

	public synchronized void percorreDiretorio(Path origem, Path destino) throws IOException {

		DirectoryStream<Path> entradasOrigem = null;

		criaDiretorio(origem, destino);

		// Lista do conteudo do diretorio
		entradasOrigem = Files.newDirectoryStream(origem);

		// Percorre o conteudo do diretorio
		for (Path path : entradasOrigem) {
			
			System.out.println(path.toAbsolutePath());
			
			Path novoDestino = destino.resolve(path.getFileName());
			
			if(Files.isDirectory(path)){
				percorreDiretorio(path, novoDestino);
			}
			
			/*
			// Gera o novo destino
			Path novoDestino = destino.resolve(path.getFileName());
			
			Backup backup = new Backup();
			backup.setNomeArquivo(path.toFile().getAbsolutePath().replace(this.caminhoOrigem, ""));
			backup.setUltimaModificacao(Files.getLastModifiedTime(path).toMillis());
			
			System.out.println(path.getFileName());
			
			if(Files.exists(novoDestino)) {			
				
				// Verifica se eh um diretorio
				if (Files.isDirectory(path)) {
					// Invoca o metodo de maneira recursiva
					percorreDiretorio(path, novoDestino);

				} else {
					copiaArquivo(path, novoDestino);
				}
				
				if(!listaArquivos.contains(backup)) {
					listaArquivos.add(backup);
				} else {
					listaArquivos.get(listaArquivos.indexOf(backup)).setUltimaModificacao(Files.getLastModifiedTime(path).toMillis());
				}
							
			} else {

				if(listaArquivos.contains(backup)) {
					
					if(listaArquivos.get(listaArquivos.indexOf(backup)).getUltimaModificacao() == Files.getLastModifiedTime(path).toMillis()) {
						listaArquivos.remove(backup);
						Files.delete(path);
					} else {
						listaArquivos.get(listaArquivos.indexOf(backup)).setUltimaModificacao(Files.getLastModifiedTime(path).toMillis());
						// Verifica se eh um diretorio
						if (Files.isDirectory(path)) {
							// Invoca o metodo de maneira recursiva
							percorreDiretorio(path, novoDestino);

						} else {
							copiaArquivo(path, novoDestino);
						}
					}							
					
				} else {
					// Verifica se eh um diretorio
					if (Files.isDirectory(path)) {
						// Invoca o metodo de maneira recursiva
						percorreDiretorio(path, novoDestino);

					} else {
						copiaArquivo(path, novoDestino);
					}
					
					listaArquivos.add(backup);
				}
									
			}
			
			entradasOrigem = Files.newDirectoryStream(origem);*/

		}

	}

	private void copiaArquivo(Path origem, Path destino) throws IOException {

		// Verifica se o arquivo ja existe no destino
		if (Files.exists(destino)) {

			FileTime fileTimeOrigem = Files.getLastModifiedTime(origem);
			FileTime fileTimeDestino = Files.getLastModifiedTime(destino);

			// Verifica de a data de modificacao da origem e maior que a
			// destino, se sim sobrescreve o arquivo
			if (fileTimeOrigem.toMillis() > fileTimeDestino.toMillis()) {

				Files.copy(origem, destino,
						StandardCopyOption.REPLACE_EXISTING,
						StandardCopyOption.COPY_ATTRIBUTES);
			}
		} else {
				
			// Se arquivo nao existe, faz a copia para o diretorio de destino
			Files.copy(origem, destino, StandardCopyOption.COPY_ATTRIBUTES);
		
		}
	}

	private void criaDiretorio(Path origem, Path destino) throws IOException {
		// Verifica se o diretorio existe no destino
		if (!Files.exists(destino)) {

			// Cria diretorio
			Files.createDirectories(destino);
			// Seta a data de moficacao da origem no destino
			Files.setLastModifiedTime(destino, Files.getLastModifiedTime(origem));

		}
	}

	public String getDestino() {
		return destino;
	}

	public void setDestino(String destino) {
		this.destino = destino;
	}

	public String getOrigem() {
		return caminhoOrigem;
	}

	public void setOrigem(String origem) {
		this.caminhoOrigem = origem;
	}

}